home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / pluginy Firefox / 52811 / 52811.xpi / chrome / content / AES / entropy.js < prev    next >
Encoding:
JavaScript  |  2009-08-22  |  6.4 KB  |  177 lines

  1.     //  Entropy collection utilities
  2.     /* 
  3.     In information theory, entropy is a measure of the uncertainty associated 
  4.     with a random variable. The term by itself in this context usually refers 
  5.     to the Shannon entropy, which quantifies, in the sense of an expected 
  6.     value, the information contained in a message, usually in units such as 
  7.     bits. Equivalently, the Shannon entropy is a measure of the average 
  8.     information content one is missing when one does not know the value of the 
  9.     random variable. The concept was introduced by Claude E. Shannon in his 
  10.     1948 paper "A Mathematical Theory of Communication".
  11.  
  12.     Shannon's entropy represents an absolute limit on the best possible 
  13.     lossless compression of any communication, under certain constraints: 
  14.     treating messages to be encoded as a sequence of independent and 
  15.     identically-distributed random variables, Shannon's source coding theorem 
  16.     shows that, in the limit, the average length of the shortest possible 
  17.     representation to encode the messages in a given alphabet is their entropy 
  18.     divided by the logarithm of the number of symbols in the target alphabet.
  19.  
  20.     A fair coin has an entropy of one bit. However, if the coin is not fair, 
  21.     then the uncertainty is lower (if asked to bet on the next outcome, we 
  22.     would bet preferentially on the most frequent result), and thus the Shannon 
  23.     entropy is lower. Mathematically, a coin flip is an example of a Bernoulli 
  24.     trial, and its entropy is given by the binary entropy function. A long 
  25.     string of repeating characters has an entropy rate of 0, since every 
  26.     character is predictable. The entropy rate of English text is between 1.0 
  27.     and 1.5 bits per letter,[1] or as low as 0.6 to 1.3 bits per letter, 
  28.     according to estimates by Shannon based on human experiments.
  29.     From: http://en.wikipedia.org/wiki/Entropy_(information_theory)
  30.     */
  31.     
  32.     /*    Start by declaring static storage and initialise
  33.         the entropy vector from the time we come through
  34.         here. */
  35.     
  36.     var entropyData = new Array();           // Collected entropy data
  37.     var edlen = 0;                          // Keyboard array data length
  38.  
  39.     addEntropyTime();                        // Start entropy collection with page load time
  40.     ce();                                   // Roll milliseconds into initial entropy
  41.  
  42.     //    Add a byte to the entropy vector
  43.     
  44.     function addEntropyByte(b) {
  45.         entropyData[edlen++] = b;
  46.     }
  47.             
  48.     /*    Capture entropy.  When the user presses a key or performs
  49.     various other events for which we can request
  50.     notification, add the time in 255ths of a second to the
  51.     entropyData array.  The name of the function is short
  52.     so it doesn't bloat the form object declarations in
  53.     which it appears in various "onXXX" events.  */
  54.     
  55.     function ce() {
  56.         addEntropyByte(Math.floor((((new Date).getMilliseconds()) * 255) / 999));
  57.     }
  58.     
  59.     //    Add a 32 bit quantity to the entropy vector
  60.     
  61.     function addEntropy32(w) {
  62.         var i;
  63.     
  64.     for (i = 0; i < 4; i++) {
  65.         addEntropyByte(w & 0xFF);
  66.         w >>= 8;
  67.         }
  68.     }
  69.     
  70.     /*    Add the current time and date (milliseconds since the epoch,
  71.         truncated to 32 bits) to the entropy vector.  */
  72.     
  73.     function addEntropyTime() {
  74.         addEntropy32((new Date()).getTime());
  75.     }
  76.  
  77.     /*  Start collection of entropy from mouse movements. The
  78.     argument specifies the  number of entropy items to be
  79.     obtained from mouse motion, after which mouse motion
  80.     will be ignored.  Note that you can re-enable mouse
  81.     motion collection at any time if not already underway.  */
  82.     
  83.     var mouseMotionCollect = 0;
  84.     var oldMoveHandler;             // For saving and restoring mouse move handler in IE4
  85.     
  86.     function mouseMotionEntropy(maxsamp) {
  87.         if (mouseMotionCollect <= 0) {
  88.         mouseMotionCollect = maxsamp;
  89.             if ((document.implementation.hasFeature("Events", "2.0")) &&
  90.             document.addEventListener) {
  91.                 //  Browser supports Document Object Model (DOM) 2 events
  92.         document.addEventListener("mousemove", mouseMoveEntropy, false);
  93.         } else {
  94.         if (document.attachEvent) {
  95.                 //  Internet Explorer 5 and above event model
  96.             document.attachEvent("onmousemove", mouseMoveEntropy);
  97.         } else {
  98.             //    Internet Explorer 4 event model
  99.                 oldMoveHandler = document.onmousemove;
  100.             document.onmousemove = mouseMoveEntropy;
  101.         }
  102.         }
  103. //dump("Mouse enable", mouseMotionCollect);
  104.     }
  105.     }
  106.     
  107.     /*    Collect entropy from mouse motion events.  Note that
  108.         this is craftily coded to work with either DOM2 or Internet
  109.     Explorer style events.  Note that we don't use every successive
  110.     mouse movement event.  Instead, we XOR the three bytes collected
  111.     from the mouse and use that to determine how many subsequent
  112.     mouse movements we ignore before capturing the next one.  */
  113.     
  114.     var mouseEntropyTime = 0;        // Delay counter for mouse entropy collection
  115.     
  116.     function mouseMoveEntropy(e) {
  117.         if (!e) {
  118.         e = window.event;        // Internet Explorer event model
  119.     }
  120.     if (mouseMotionCollect > 0) {
  121.         if (mouseEntropyTime-- <= 0) {
  122.             addEntropyByte(e.screenX & 0xFF);
  123.             addEntropyByte(e.screenY & 0xFF);
  124.             ce();
  125.             mouseMotionCollect--;
  126.             mouseEntropyTime = (entropyData[edlen - 3] ^ entropyData[edlen - 2] ^
  127.                             entropyData[edlen - 1]) % 19;
  128. //dump("Mouse Move", byteArrayToHex(entropyData.slice(-3)));
  129.             }
  130.         if (mouseMotionCollect <= 0) {
  131.             if (document.removeEventListener) {
  132.             document.removeEventListener("mousemove", mouseMoveEntropy, false);
  133.         } else if (document.detachEvent) {
  134.             document.detachEvent("onmousemove", mouseMoveEntropy);
  135.         } else {
  136.             document.onmousemove = oldMoveHandler;
  137.         }
  138. //dump("Spung!", 0);
  139.         }
  140.     }
  141.     }    
  142.     
  143.     /*    Compute a 32 byte key value from the entropy vector.
  144.         We compute the value by taking the MD5 sum of the even
  145.     and odd bytes respectively of the entropy vector, then
  146.     concatenating the two MD5 sums.  */
  147.     
  148.     function keyFromEntropy() {
  149.     var i, k = new Array(32);
  150.     
  151.     if (edlen == 0) {
  152.         alert(strBundle.getFormattedString("entropyErrMessage", [ "keyFromEntropy" ]));
  153.     }
  154. //dump("Entropy bytes", edlen);
  155.  
  156.     md5_init();
  157.     for (i = 0; i < edlen; i += 2) {
  158.         md5_update(entropyData[i]);
  159.     }
  160.     md5_finish();
  161.         for (i = 0; i < 16; i++) {
  162.         k[i] = digestBits[i];
  163.     }
  164.  
  165.     md5_init();
  166.     for (i = 1; i < edlen; i += 2) {
  167.         md5_update(entropyData[i]);
  168.     }
  169.     md5_finish();
  170.         for (i = 0; i < 16; i++) {
  171.         k[i + 16] = digestBits[i];
  172.     }
  173.     
  174. //dump("keyFromEntropy", byteArrayToHex(k));
  175.     return k;
  176.     }
  177.